/**
 * Place data according to keys, 1 key : n data
 * @param {array} keys
 * @param {array} data
 * @param {string} groupKey
 * @param {string} defVal
 * @return {array} rearranged data array
 */
export const groupData = (keys, data, groupKey, defVal) => {
  // Use index of keys for data group referencing
  let keyMap = keys.reduce((obj, item, i) => {
    obj[item] = i
    return obj
  }, {})

  // Initialize array
  for (var i = 0, size = keys.length, array = new Array(size); i < size; i++) {
    array[i] = defVal == null ? [] : defVal
  }
  // Group data by target id
  var result = data.reduce(function(obj, item) {
    // It's m:n relation if groupKey is an array
    if (Array.isArray(item[groupKey])) {
      for (let i = 0; i < item[groupKey].length; i++) {
        let key = item[groupKey][i]
        obj[keyMap[key]] = obj[keyMap[key]] || []
        obj[keyMap[key]].push(item)
      }
    } else {
      obj[keyMap[item[groupKey]]] = obj[keyMap[item[groupKey]]] || []
      obj[keyMap[item[groupKey]]].push(item)
    }
    return obj
  }, array)
  return result
}

/**
 * Place data according to keys, 1 key : 1 data
 * @param {array} keys
 * @param {array} data
 * @param {string} groupKey
 * @param {string} valKey
 * @return {array} rearranged data
 */
export const placeData = (keys, data, groupKey, defVal, fieldKey) => {
  // Use index of keys for data group referencing
  let keyMap = keys.reduce((obj, item, i) => {
    obj[item] = i
    return obj
  }, {})

  // Initialize array
  // Initialize array
  for (var i = 0, size = keys.length, array = new Array(size); i < size; i++) {
    array[i] = defVal
  }
  // Group data by target id
  var result = data.reduce(function(obj, item) {
    obj[keyMap[item[groupKey]]] = fieldKey ? item[fieldKey] : item
    return obj
  }, array)
  return result
}
